<template>
  <div class="home">
    <bs-scroller
      :data="dataList"
      :pullup="true"
      :pulldown="true"
      @pullup="getDataList"
      @pullDownRefresh="getDataList('refresh')"
    >
      <div style="height:200%">
        <!-- <van-button type="primary" size="mini">vant button</van-button> -->
        <div style="display:flex" class="dd">
          <input class="button_success" @click="handleFileChange" type="file"/>
          
          <div class="button_primary" @click="handleUploadFile">上传</div>
          <div class="button_danger" @click="stopUpload">暂停</div>
          <div class="button_warn" @click="continueUpload">继续</div>
          <!-- <div class="button_success">goBack</div> -->
        </div>
      </div>
    </bs-scroller>
  </div>
</template>

<script>
import BsScroller from "../components/BSScroller.vue";
import SparkMD5 from "spark-md5";
import axios from "axios";
const cancelToken = axios.CancelToken;
// @ is an alias to /src
const chunkSize = 5 * 1024 * 1024; //分片大小
let currentFile = null;
let chunkFormData = [];
let fileHash = null;
export default {
  name: "Home",
  components: { BsScroller },
  data() {
    return {
      dataList: [],
      stopPullUp: false, //是否停止上拉加载
    };
  },
  methods: {
    getDataList() {
      console.log("触发请求数据....");
      this.dataList.push("");
    },
    handleFileChange(file) {
      if (!file) return;
      console.log(file);
      currentFile = file;
    },
    /**
     * @description: 文件上传 Click 事件
     * @param {*}
     * @return {*}
     */
    async handleUploadFile() {
      if (!currentFile) {
        this.$dialog({
          message: "请选择文件",
        });
        return;
      }
      // 文件分片
      let fileChunkList = this.createChunkList(currentFile, chunkSize);
      // 文件hash
      fileHash = await this.createMD5(fileChunkList, chunkSize);

      // 判断文件是否存在 发起请求
      // let { isUploaded } = await verifyUpload({
      //   fileHash: fileHash.value,
      //   fileName: currentFile.value.name,
      // });
      // if (isUploaded) {
      //   ElMessage.warning("文件已存在");
      //   return;
      // }

      let chunkList = fileChunkList.map((file, index) => {
        return {
          file: file,
          chunkHash: fileHash + "-" + index,
          fileHash: fileHash,
        };
      });

      chunkFormData = chunkList.map((chunk) => {
        let formData = new FormData();
        formData.append("chunk", chunk.file);
        formData.append("chunkHash", chunk.chunkHash);
        formData.append("fileHash", chunk.fileHash);
        return {
          formData: formData,
          percentage: 0,
          cancelToken: cancelToken.source(),
        };
      });

      continueUpload();
    },
    /**
     * @description: 暂停上传 Click 事件
     * @param {*}
     * @return {*}
     */
    stopUpload() {
      chunkFormData.forEach((data) => {
        data.cancelToken.cancel("取消上传");
        data.cancelToken = cancelToken.source();
      });
    },
    /**
     * @description: 继续上传 Click 事件
     * @param {*}
     * @return {*}
     */
    continueUpload() {
      let notUploaded = chunkFormData.filter((item) => !item.precentage);

      Promise.all(
        notUploaded.map((data) => {
          //发起上传请求
          // postUploadFile(
          //   data.formData,
          //   uploadProgress(data),
          //   data.cancelToken.token
          // );
        })
      ).then((data) => {
        if (!data.includes(undefined)) {
          //请求合并文件
          // mergeUploadFile({
          //   fileName: currentFile.value.name,
          //   fileHash: fileHash.value,
          //   chunkSize: chunkSize,
          // });
        }
      });
    },

    /**
     * @description: 1 创建文件分片
     * @param {*}
     * @return {*}
     */
    createChunkList(file, chunkSize) {
      console.log(file);
      const fileChunkList = [];
      let cur = 0;
      while (cur < file.size) {
        fileChunkList.push(file.slice(cur, cur + chunkSize));
        cur += chunkSize;
      }
      return fileChunkList;
    },
    /**
     * @description: 2 生成文件Hash
     * @param {*}
     * @return {*}
     */
    createMD5(fileChunkList) {
      return new Promise((resolve, reject) => {
        const slice =
          File.prototype.slice ||
          File.prototype.mozSlice ||
          File.prototype.webkitSlice;

        const chucks = fileChunkList.length;
        let currentChunk = 0;
        let spark = new new SparkMD5.ArrayBuffer()();
        let fileReader = new FileReader();
        //
        fileReader.onload = (e) => {
          spark.append(e.target.result);
          currentChunk++;
          if (currentChunk < chucks) {
            loadChunk();
          } else {
            resolve(spark.end());
          }
        };
        //
        fileReader.onerror = function(e) {
          reject(e);
        };

        function loadChunk() {
          fileReader.readAsArrayBuffer(fileChunkList[currentChunk]);
        }

        loadChunk();
      });
    },
  },
  mounted() {
    this.getDataList();
  },
};
</script>

<style lang="scss" scoped>
.home {
  width: 100%;
  height: 100%;
  // padding: 30px;
  .dd {
    * {
      margin: 10px;
    }
  }
}
</style>
